package com.github.eden.db;

import com.github.eden.config.Config;
import com.github.eden.util.Utils;
import org.apache.commons.lang3.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class DbTableParser {

    private Config config;

    public DbTableParser(Config config) {
        this.config = config;
    }

    public void parse(List<DbTable> tables) {
        for (DbTable table : tables) {
            table.setObjectName(Utils.toCamelCase(table.getTableName()));
            table.setClassName(Utils.toBigCamelCase(table.getTableName()));
            table.setIsRelationalTable(table.getTableName().endsWith("_rel"));
            table.setMenuName(table.getTableComment());

            for (DbColumn column : table.getColumns()) {
                column.setFieldType(columnTypeToFieldType(column.getColumnType()));
                column.setFieldFullType(columnTypeToFieldFullType(column.getColumnType()));

                if (column.getIsPrimaryKeyColumn()) {
                    table.setPrimaryKeyColumn(column);
                }
                if (column.getColumnName().equals(config.getCreateTimeColumn())) {
                    column.setIsCreateTimeColumn(true);
                    table.setCreateTimeColumn(column);
                }
                if (column.getColumnName().equals(config.getUpdateTimeColumn())) {
                    column.setIsUpdateTimeColumn(true);
                    table.setUpdateTimeColumn(column);
                }
                if (column.getColumnName().equals(config.getDeletedColumn())) {
                    column.setIsDeletedColumn(true);
                    table.setDeletedColumn(column);
                }

                parseColumnComment(column);
            }
        }
    }

    /**
     * 分隔符层级: # , :
     * label#component#k:v,k:v
     * 用户角色#select#0:普通用户,1:管理员
     * componentType: input, select, textarea, radio, checkbox, switch, input-number
     * @param column
     */
    private static void parseColumnComment(DbColumn column) {
        String[] comments = StringUtils.split(column.getColumnComment(), "#");
        if (comments.length == 1) {
            column.setUiLabelName(comments[0]);
        } else if (comments.length == 2) {
            column.setUiLabelName(comments[0]);
            column.setUiComponentType(comments[1]);
        } else {
            column.setUiLabelName(comments[0]);
            column.setUiComponentType(comments[1]);

            String[] kvs = StringUtils.split(comments[2], ",");
            if (kvs != null) {
                Map<String, String> kvMap = new LinkedHashMap<>();
                for (String kvStr : kvs) {
                    String[] kv = StringUtils.split(kvStr, ":");
                    if (kv != null && kv.length >= 2) {
                        kvMap.put(kv[0], kv[1]);
                    }
                }
                column.setUiKeyValues(kvMap);
            }
        }
    }

    private static String columnTypeToFieldFullType(String columnType) {
        String type = columnType.toUpperCase();
        if (type.contains("CHAR")) {
            return "java.lang.String";
        } else if (type.contains("BIGINT")) {
            return "java.lang.Long";
        } else if (type.contains("INT")) {
            return "java.lang.Integer";
        } else if (type.contains("DATE")) {
            return "java.util.Date";
        } else if (type.contains("TIMESTAMP")) {
            return "java.util.Date";
        } else if (type.contains("TEXT")) {
            return "java.lang.String";
        } else if (type.contains("BIT")) {
            return "java.lang.Boolean";
        } else if (type.contains("DECIMAL")) {
            return "java.math.BigDecimal";
        } else if (type.contains("BLOB")) {
            return "byte[]";
        } else if (type.contains("FLOAT")) {
            return "java.lang.Float";
        } else if (type.contains("DOUBLE")) {
            return "java.lang.Double";
        } else {
            return "java.lang.Object";
        }
    }

    private static String columnTypeToFieldType(String columnType) {
        String fullType = columnTypeToFieldFullType(columnType);
        String type = StringUtils.substringAfterLast(fullType, ".");
        if (StringUtils.isBlank(type)) {
            return fullType;
        }
        return type;
    }

    public static void main(String[] args) {
        System.out.println(columnTypeToFieldType("DOUBLE"));
    }
}
